package org.dolphin.action.customer;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.InterceptorRefs;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.dolphin.base.bean.CityVO;
import org.dolphin.base.bean.CustomerVO;
import org.dolphin.base.bean.FlatCustomerVO;
import org.dolphin.base.constant.Status;
import org.dolphin.base.json.PaginationBean;
import org.dolphin.base.json.StatusBean;
import org.dolphin.entity.customer.Customer;
import org.dolphin.entity.district.Address;
import org.dolphin.entity.district.City;
import org.dolphin.service.CustomerService;
import org.dolphin.service.DistrictService;
import org.dolphin.util.ExceptionHelper;
import org.dolphin.util.Pagination;
import org.hibernate.criterion.Order;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import com.opensymphony.xwork2.ActionSupport;

@ParentPackage(value = "custom-default")
@Namespace(value = "/customer")
@InterceptorRefs(value = {@InterceptorRef(value = "customStack")})
public class CustomerAction extends ActionSupport {
  private static final long serialVersionUID = 1005503173917359226L;
  private Integer page;
  private Integer rows;
  private String sidx;
  private String sord;
  private PaginationBean pagination;
  private CustomerService customerService;
  private DistrictService districtService;
  private CustomerVO customer;
  private StatusBean status;

  @Action(value = "addCustomer", results = @Result(name = "success", location = "addCustomer.jsp"))
  public String addCustomer() {
    return SUCCESS;
  }

  @Action(value = "createCustomer", results = @Result(name = "success", params = {"root", "status"}, type = "json"))
  public String createCustomer() {
    boolean error = false;
    String msg = "";
    status = new StatusBean();
    try {
      String cityId = customer.getCity().getId();
      City city = districtService.loadCity(cityId);

      Address address = new Address();
      address.setStreet(customer.getStreet());
      address.setPostalCode(customer.getPostalCode());
      address.setCity(city);

      Customer c = new Customer();
      c.setFirstname(customer.getFirstname());
      c.setLastname(customer.getLastname());
      c.setAlias(customer.getAlias());
      c.setPhone(customer.getPhone());
      c.setMobile(customer.getMobile());
      c.setFax(customer.getFax());
      c.setEmail(customer.getEmail());
      c.setAddress(address);
      getCustomerService().createCustomer(c);
    } catch (Exception e) {
      error = true;
      msg = ExceptionHelper.getRootCause(e).getMessage();
    } finally {
      status.setStatus(error ? Status.ERROR : Status.SUCCESS);
      if (error && msg != null) {
        status.addError(msg);
      }
    }
    return SUCCESS;
  }

  @Action(value = "editCustomer", results = @Result(name = "success", location = "editCustomer.jsp"))
  public String editCustomer() {
    Long id = customer.getId();
    customer = customerService.getCustomer(id);
    return SUCCESS;
  }

  public CustomerVO getCustomer() {
    return customer;
  }

  @Action(value = "getCustomers", results = @Result(name = "success", params = {"root",
      "pagination"}, type = "json"))
  public String getCustomers() {
    List<Order> orders = null;
    if (StringUtils.hasText(getSidx())) {
      orders = new ArrayList<Order>(1);
      Order order = ObjectUtils.nullSafeEquals("desc", getSord()) ? Order.desc(getSidx()) : Order
          .asc(getSidx());
      orders.add(order);
    }
    List<FlatCustomerVO> results = getCustomerService().getCustomers(page, rows, orders);
    Long records = getCustomerService().getCustomersCount();
    Integer total = Pagination.calculateTotalPage(records, getRows());
    pagination = new PaginationBean();
    pagination.setPage(getPage());
    pagination.setRecords(records);
    pagination.setTotal(total);
    pagination.setRows(results);
    return SUCCESS;
  }

  public CustomerService getCustomerService() {
    return customerService;
  }

  public DistrictService getDistrictService() {
    return districtService;
  }

  public Integer getPage() {
    return page;
  }

  public PaginationBean getPagination() {
    return pagination;
  }

  public Integer getRows() {
    return rows;
  }

  public String getSidx() {
    return sidx;
  }

  public String getSord() {
    return sord;
  }

  public StatusBean getStatus() {
    return status;
  }

  @Action(value = "listCustomer", results = @Result(name = "success", location = "listCustomer.jsp"))
  public String listCustomer() throws IOException {
    return SUCCESS;
  }

  @Action(value = "loadCustomer", results = @Result(name = "success", params = {"root", "customer"}, type = "json"))
  public String loadCustomer() {
    Long id = customer.getId();
    customer = customerService.getCustomer(id);
    return SUCCESS;
  }

  public void setCustomer(CustomerVO customer) {
    this.customer = customer;
  }

  public void setCustomerService(CustomerService customerService) {
    this.customerService = customerService;
  }

  public void setDistrictService(DistrictService districtService) {
    this.districtService = districtService;
  }

  public void setPage(Integer page) {
    this.page = page;
  }

  public void setPagination(PaginationBean pagination) {
    this.pagination = pagination;
  }

  public void setRows(Integer rows) {
    this.rows = rows;
  }

  public void setSidx(String sidx) {
    this.sidx = sidx;
  }

  public void setSord(String sord) {
    this.sord = sord;
  }

  public void setStatus(StatusBean status) {
    this.status = status;
  }

  @Action(value = "updateCustomer", results = @Result(name = "success", params = {"root", "status"}, type = "json"))
  public String updateCustomer() {
    boolean error = false;
    String msg = "";
    status = new StatusBean();
    Customer c = null;
    try {
      Long id = customer.getId();
      CityVO cityVO = customer.getCity();
      City city = getDistrictService().loadCity(cityVO.getId());
      Address address = new Address();
      address.setStreet(customer.getStreet());
      address.setCity(city);
      address.setPostalCode(customer.getPostalCode());
      c = getCustomerService().fetchCustomer(id);
      c.setVersion(customer.getVersion());
      c.setAlias(customer.getAlias());
      c.setFirstname(customer.getFirstname());
      c.setLastname(customer.getLastname());
      c.setAddress(address);
      c.setPhone(customer.getPhone());
      c.setMobile(customer.getMobile());
      c.setFax(customer.getFax());
      c.setEmail(customer.getEmail());
      getCustomerService().updateCustomer(c);
    } catch (Exception e) {
      error = true;
      msg = ExceptionHelper.getRootCause(e).getMessage();
    } finally {
      status.setStatus(error ? Status.ERROR : Status.SUCCESS);
      if (error && msg != null) {
        status.addError(msg);
      } else {
        if (c != null) {
          status.addAttr("version", c.getVersion());
        }
      }
    }
    return SUCCESS;
  }

  @Action(value = "viewCustomer", results = @Result(name = "success", location = "viewCustomer.jsp"))
  public String viewCustomer() {
    Long id = customer.getId();
    customer = getCustomerService().getCustomer(id);
    return SUCCESS;
  }
}
